Rupture avec le procédural, définition rigoureuse des classes et instances, encapsulation et invariants de classe, pointeur this, cycle de vie en mémoire, constructeurs, destructeur, opérateur d'affectation et Règle des Trois avec exemples sur les tableaux dynamiques.
Programmation Orientée Objet & Modélisation Avancée en C++
Bienvenue sur le portail pédagogique du cours de Programmation Orientée Objet. Ce cours a pour objectif de vous faire acquérir les compétences théoriques et pratiques indispensables pour concevoir des logiciels robustes, modulaires et performants en C++.
Compétences visées au terme de l'unité d'enseignement
- Comprendre et appliquer le paradigme objet par opposition au paradigme procédural.
- Maîtriser la gestion manuelle et sûre des ressources en mémoire (idiome RAII et Règle des Trois).
- Concevoir des hiérarchies de classes complexes (héritage simple, multiple et résolution du diamant par héritage virtuel).
- Développer des composants réutilisables et des conteneurs performants grâce à la généricité (Templates).
Note concernant l'IA
Ces pages ont été réalisées grâce à Gemini de Google. Certaines affirmations concernant la programmation orientée objet sont parfois discutables et elles seront explicitées en cours.
Programme et Accès aux Chapitres
Le cours est structuré en chapitres progressifs avec coloration syntaxique dynamique assurée par GeSHi, alternant explications théoriques, schémas mémoires, exemples C++ compilés et QCM d'auto-évaluation interactifs :
Sémantique de la relation « EST-UN » vs composition, modes de dérivation, ordre strict d'exécution des constructeurs et destructeurs, gestion des collisions de noms en héritage multiple et résolution du problème du diamant grâce à l'héritage virtuel (virtual).
Programmation générique et typage statique fort, patrons de fonctions (function templates), instanciation à la compilation, patrons de classes et conteneurs génériques (Pile<T> dynamique), paramètres non-types et règle d'organisation des fichiers d'en-tête (.hpp / .tpp).
Architecture tripartite de la STL (conteneurs, itérateurs, algorithmes), flux d'entrées/sorties std::cout et std::cerr (tamponné vs non-tamponné), conteneurs séquentiels et associatifs (vector, set, map), et algorithmes génériques fondamentaux (sort, reverse, count, count_if) avec expressions lambdas simples.
Transposition des concepts objets en Python : self et constructeurs, encapsulation pythonique (conventions, name mangling, @property), polymorphisme dynamique par Duck Typing, résolution automatique du diamant d'héritage par le MRO (C3) et étude comparative de ce qui est possible ou impossible par rapport au C++ (surcharge par signature, RAII vs with, méthodes dunder).
Complément aux chapitres du cours traitant des sujets vitaux non abordés : la gestion robuste des exceptions et l'exigence noexcept, les pointeurs intelligents (unique_ptr, shared_ptr, weak_ptr), la sémantique de déplacement et la Règle des Cinq (T&&, std::move), l'amitié (friend) pour la surcharge des opérateurs de flux << / >>, les membres statiques de classe et le transtypage dynamique sécurisé (RTTI / dynamic_cast).
Travaux Dirigés & Exercices Pratiques
Les séances de Travaux Dirigés permettent d'ancrer la théorie par la pratique intensive du code en C++20. Chaque TD propose des exercices progressifs avec conseils méthodologiques, indices et corrigés détaillés dépliables :
5 exercices progressifs de difficulté croissante : passage du procédural à l'objet avec Point2D, protection des invariants temporels avec Duree et interface fluide via *this, composition d'objets et ordre d'appel du cycle de vie mémoire, mise en évidence expérimentale du crash par Double Free avec VecteurDynamique, et conception intégrale de la classe Chaine (String maison) appliquant la Règle des Trois.
5 exercices progressifs de difficulté croissante : spécialisation avec Employe, Manager et Developpeur, traçage du cycle de vie mémoire LIFO et résolution du masquage de noms (Name Hiding) avec using, étude comparative des modes de dérivation (public vs private) et rupture du sous-typage, héritage multiple avec CopieurMultifonction et mesure des offsets mémoire, et résolution du problème du diamant avec l'héritage virtuel (VehiculeAmphibie).
5 exercices progressifs de difficulté croissante : patrons de fonctions et déduction automatique de types (echanger, maximum, trouverIndice), paramètres non-types (NTTP) avec TableauStatique<T, N> alloué sur la pile, spécialisation totale et partielle de patrons (résolution du piège des pointeurs const char* et formateur adaptatif), conteneur dynamique VecteurGenerique<T> appliquant la Règle des Trois, et conception d'une file d'attente chaînée FIFO (FileGenerique<T>) en $O(1)$ avec gestion robuste des exceptions.
Environnement de Travail & Bonnes Pratiques
🛠️ Compilation recommandée (C++20)
Pour compiler les exemples du répertoire code/ avec le maximum d'avertissements utiles :
g++ -std=c++20 -Wall -Wextra -pedantic code/Rectangle.cpp -o rect ./rect
🔍 Détection de fuites mémoire (Sanitizers & Valgrind)
Pour traquer les fuites mémoire et doubles libérations (Double Free) :
# Compilation avec AddressSanitizer (recommandé) g++ -std=c++20 -fsanitize=address -g code/TableauInt.cpp -o tab ./tab # Analyse Valgrind valgrind --leak-check=full ./tab
1. Dessinez la mémoire : Prenez toujours une feuille pour représenter les objets sur la pile et les allocations sur le tas.
2. Pensez RAII : Chaque ressource allouée avec new doit avoir son correspondant automatique delete dans le destructeur.
3. Appliquez la Règle des Trois : Dès qu'une classe alloue de la mémoire dynamique, écrivez explicitement destructeur, constructeur par copie et operator=.